import React, { useRef, useState, ElementRef, forwardRef, useImperativeHandle } from 'react';
import { cloneDeep } from 'lodash';
import { Form, Input, Radio, Tag, InputNumber, Expand } from '@block/plug';
import { CollapseList, ParkerRichText } from '@src/components';
import { getUUid, RiskLevel } from '@src/utils';
import { BusinessFeedbackTable } from '../../elements';
import { PROBLEM_LIST_MAX, PROBLEM_MAX_LENGTH, PROBLEM_TITLE_MAX_LENGTH } from '../../constant';
import { AuditFindingsItem } from '../../types';
import './AuditFindingItem.scss';

interface Props {
  value?: AuditFindingsItem[];
  onChange?: (val: AuditFindingsItem[]) => void;
  mode: Mode;
  findingItemCnt: number;
  onTransfer: (fromGroupIndex: number, fromItemIndex: number, toGroupIndex: number, toItemIndex: number) => void;
  /** 当前所在的审计发现组下标 */
  parentGroupIndex: number;
  riskGradeList: SelectOption[];
}

interface Handle {
  /** 表单校验 */
  onValidate: () => boolean;
}

/**
 * 单个审计发现详述
 */
const AuditFindingItem = forwardRef<Handle, Props>((props, ref) => {
  const { value, onChange, mode, findingItemCnt, onTransfer, parentGroupIndex, riskGradeList = [] } = props;

  /** 头部表单Form列表 */
  const headerFormListRef = useRef<Array<Form>>([]);
  /** 内容表单Form列表 */
  const contentFormListRef = useRef<Array<Form>>([]);
  /** 业务方反馈表格 */
  const businessTableRef = useRef<ElementRef<typeof BusinessFeedbackTable>>();
  /** 富文本实例列表 */
  const richTextListRef = useRef<Array<ElementRef<typeof ParkerRichText>>>([]);

  /** 移动目标组下标 */
  const [transferToGroupIndex, setTransferToGroupIndex] = useState<number>(parentGroupIndex + 1);
  /** 移动目标组下第几位下标 */
  const [transferToItemIndex, setTransferToItemIndex] = useState<number>();

  const getAddInitData = (): Partial<AuditFindingsItem> => ({
    problemId: getUUid('string') as string,
  });

  /**
   * 表单change事件
   * @param key formItemKey
   * @param val item值
   * @param index 列表下标
   */
  const handleFormChange = (key: string, val, index: number) => {
    const newDataList = cloneDeep(value);
    newDataList[index] = { ...(newDataList?.[index] ?? {}), [key]: val };
    onChange?.(newDataList);
  };

  const handleListChange = (val: AuditFindingsItem[]) => {
    onChange?.(val);
  };

  const handleValidate = () => {
    let validate = true;
    headerFormListRef.current?.forEach((formRef) => {
      if (formRef) {
        const headerValidate = formRef?.validateFields();
        if (validate && !headerValidate) validate = false;
      }
    });
    contentFormListRef.current?.forEach((formRef) => {
      if (formRef) {
        const contentValidate = formRef?.validateFields();
        if (validate && !contentValidate) validate = false;
      }
    });
    const tableValidate = businessTableRef.current?.onValidate?.();
    return validate && tableValidate;
  };

  useImperativeHandle(ref, () => ({ onValidate: handleValidate }));

  const renderTitle = (val: AuditFindingsItem, index: number) => {
    const { problemIndex } = val ?? {};
    if (mode === 'edit') {
      return (
        <div className="title-tag">
          <div className="serial-num">序号{index + 1}</div>
          <Tag theme="gray" type="pure">
            审计发现{problemIndex}
          </Tag>
        </div>
      );
    }
    return (
      <Tag theme="gray" type="pure">
        审计发现{problemIndex}
      </Tag>
    );
  };

  /** 风险等级view态颜色 */
  const renderRiskLevel = (riskLevelValue: RiskLevel) => {
    switch (riskLevelValue) {
      case RiskLevel.high:
        return <Tag theme="red">高风险</Tag>;
      case RiskLevel.medium:
        return <Tag theme="orange">中风险</Tag>;
      case RiskLevel.low:
        return <Tag theme="green">低风险</Tag>;
      default:
        return '-';
    }
  };

  const renderCardHeadSelect = (val: AuditFindingsItem, index: number) => {
    const { title } = val ?? {};
    return (
      <Form
        className="audit-finding-item-header-form"
        ref={(formRef: Form) => {
          headerFormListRef.current[index] = formRef;
        }}
        mode={mode}
        defaultFieldsValue={{ title }}
        onFieldValueChange={(formKey, formVal) => handleFormChange(formKey, formVal, index)}
      >
        <Form.Item
          formItemKey="title"
          label="标题："
          rules={[
            { required: true, whitespace: true, message: '请输入标题' },
            { max: PROBLEM_TITLE_MAX_LENGTH, message: `不允许超过${PROBLEM_TITLE_MAX_LENGTH}字符` },
          ]}
        >
          {({ value: titleValue }) => {
            if (mode === 'view' && titleValue) {
              return (
                <Expand minRows={1} newLine={false} mode="tooltip">
                  {titleValue}
                </Expand>
              );
            }
            if (mode === 'edit') {
              return (
                <Input
                  toFormItem
                  dispatchChange={['onInput']}
                  placeholder={`输入不超过${PROBLEM_TITLE_MAX_LENGTH}字符`}
                  showCount
                  maxLength={PROBLEM_TITLE_MAX_LENGTH}
                />
              );
            }
            return '-';
          }}
        </Form.Item>
      </Form>
    );
  };

  const renderCardContent = (val: AuditFindingsItem, index: number) => {
    const { riskLevel, problemDescAndRiskAnalyze, auditRecommend, businessFeedbackList } = val ?? {};
    return (
      <Form
        ref={(formRef: Form) => {
          contentFormListRef.current[index] = formRef;
        }}
        mode={mode}
        labelWidth="7em"
        defaultFieldsValue={{ riskLevel, problemDescAndRiskAnalyze, auditRecommend, businessFeedbackList }}
        onFieldValueChange={(formKey, formVal) => handleFormChange(formKey, formVal, index)}
      >
        <Form.Item formItemKey="riskLevel" label="风险等级：" required message="请选择风险等级">
          {({ value: riskLevelValue }) => {
            if (mode === 'edit') {
              return (
                <Radio.Group toFormItem>
                  {riskGradeList?.map((grade) => (
                    <Radio key={grade?.code} value={grade?.code}>
                      {grade?.name}
                    </Radio>
                  ))}
                </Radio.Group>
              );
            }
            return renderRiskLevel(riskLevelValue);
          }}
        </Form.Item>
        <Form.Item
          formItemKey="problemDescAndRiskAnalyze"
          label="问题描述及风险分析："
          rules={[
            { required: true, whitespace: true, message: '请输入问题描述及风险分析' },
            {
              validator: (config, textVal: string, callback: (str?: string) => void) => {
                if (richTextListRef.current?.[index]?.getTextCnt() > PROBLEM_MAX_LENGTH) {
                  callback(`建议不超过${PROBLEM_MAX_LENGTH}字符`);
                } else callback();
              },
            },
          ]}
        >
          {({ value: problemDescAndRiskAnalyzeValue }) => {
            if (mode === 'edit' || problemDescAndRiskAnalyzeValue?.length > 0) {
              return (
                <ParkerRichText
                  toFormItem
                  ref={(richTextRef: ElementRef<typeof ParkerRichText>) => {
                    richTextListRef.current[index] = richTextRef;
                  }}
                  placeholder={`建议不超过${PROBLEM_MAX_LENGTH}字符`}
                  showCount
                  maxLength={PROBLEM_MAX_LENGTH}
                />
              );
            }
            return '-';
          }}
        </Form.Item>
        <Form.Item
          formItemKey="auditRecommend"
          label="审计建议："
          rules={{ required: true, whitespace: true, message: '请填写审计建议' }}
        >
          {({ value: auditRecommendValue }) => {
            if (mode === 'edit' || auditRecommendValue?.length > 0) {
              return (
                <Input.TextArea
                  toFormItem
                  dispatchChange={['onInput']}
                  maxLength={PROBLEM_MAX_LENGTH}
                  showCount
                  placeholder={`输入不超过${PROBLEM_MAX_LENGTH}字符`}
                  autosize={{ minRows: 5 }}
                />
              );
            }
            return '-';
          }}
        </Form.Item>
        <Form.Item formItemKey="businessFeedbackList" label="业务方反馈：" required message="请填写业务方反馈">
          <BusinessFeedbackTable ref={businessTableRef} toFormItem mode={mode} />
        </Form.Item>
      </Form>
    );
  };

  return (
    <CollapseList<Partial<AuditFindingsItem>>
      className="audit-finding-item"
      title={renderTitle}
      // @ts-expect-error
      defaultValue={parentGroupIndex === 0 ? [0] : undefined}
      expandIconPosition="end"
      multiple
      addDisable={() => findingItemCnt >= PROBLEM_LIST_MAX}
      deleteDisable={(val, index, dataList) => dataList?.length <= 1}
      addInitData={getAddInitData}
      data={value}
      keyField="problemId"
      mode={mode}
      onChange={handleListChange}
      onTransfer={(currentItemIndex) => {
        onTransfer(parentGroupIndex, currentItemIndex, transferToGroupIndex, transferToItemIndex);
      }}
      onTransferVisibleChange={(visible) => {
        if (visible) {
          setTransferToGroupIndex(null);
          setTransferToItemIndex(null);
        }
      }}
      renderTransfer={
        <div className="audit-finding-item-transfer">
          移动至第
          <InputNumber
            className="input-number"
            // value={transferToGroupIndex}
            onChange={(num) => {
              setTransferToGroupIndex(num);
            }}
            min={1}
            precision={0}
            controls={false}
          />
          组，第
          <InputNumber
            className="input-number"
            onChange={(num) => {
              setTransferToItemIndex(num);
            }}
            min={1}
            precision={0}
            controls={false}
          />
          位
        </div>
      }
      renderHeaderSelect={renderCardHeadSelect}
      renderContent={renderCardContent}
      getContainer={() => document.querySelector('.project-detail-content') || document.body}
    />
  );
});

export default AuditFindingItem;
